#include <iostream>
#include "SystemConfig.h"

IMPLEMENT_SINGTON(CSystemConfig);
CSystemConfig::CSystemConfig(void)
{
	m_bLoad = false;
	m_nPortNo = 3;
	m_nVirPortNo = 2;
	m_nBaud =  9600;
	m_strParity = 'N';
	m_nDataBit = 8;
	m_nStopBit = 1;

	m_pMonitorCommand = new COMMAND;
	m_pTvWallCommand = new COMMAND;

	m_pMonitorCommand->nBegin				= 0XF5;
	m_pMonitorCommand->nId					= 0XB0;
	m_pMonitorCommand->nTvWallBegin	= 0X11;
	m_pMonitorCommand->nTvWallEnd		= 0XFF;
	m_pMonitorCommand->nControl			= 0XCA;
	m_pMonitorCommand->nRegulate			= 0X01;
	m_pMonitorCommand->nEnd					= 0XAE;

	m_pTvWallCommand->nBegin					= 0XF5;
	m_pTvWallCommand->nId						= 0XB0;
	m_pTvWallCommand->nTvWallBegin		= 0X11;
	m_pTvWallCommand->nTvWallEnd			= 0XFF;
	m_pTvWallCommand->nControl				= 0XCA;
	m_pTvWallCommand->nRegulate			= 0X02;
	m_pTvWallCommand->nEnd					= 0XAE;

	//m_strMonitorCommand = "0xf5b011ffca01ae";
	//m_strTvWallCommand   =  "0xf5b011ffca02ae";

	TCHAR szFullPathName[MAX_PATH] = {_T("")};
	CFileUtil::GetAppPath(szFullPathName, MAX_PATH);
	//CFileUtil::GetUserPath(szFullPathName, _T("SerialPort_communication")) ;
	//CFileUtil::CreateDirectory(szFullPathName);
		
	m_strConfigFilePath = szFullPathName;
	LoadConfig();
}

CSystemConfig::~CSystemConfig()
{
	delete m_pMonitorCommand;
	delete m_pTvWallCommand;
}

bool CSystemConfig::LoadConfig()
{
	if (m_bLoad)
		return true;

	TCHAR szAppPath[MAX_PATH] = {_T("")};
	memset(szAppPath, 0, MAX_PATH);
	int nLength = m_strConfigFilePath.length()>MAX_PATH?MAX_PATH:m_strConfigFilePath.length();
	memcpy(szAppPath , m_strConfigFilePath.c_str(), nLength);

	TCHAR szCfgFile[MAX_PATH] = {_T("")};
	CFileUtil::GetFullFileName(szAppPath,SYSTEM_CONFIG_FILE,szCfgFile,MAX_PATH);

	if(!CFileUtil::IsFileOrDirExist(szCfgFile))
	{
		CFileUtil::CreateDirectory(szAppPath);
		if (!SaveConfig())
		{
			return FALSE;
		}
	}
	try
	{
		CMarkup objDoc;
		if (!objDoc.Load(szCfgFile))
		{
			cout<<_T("Load system config file failed.")<<endl;
			return FALSE;
		}

		//serial port configuration
		if (!objDoc.FindChildElem(_T("configcenter")))
		{
			cout<<_T("Invalid system config file[no configcenter element].")<<endl;
			return false;
		}

		objDoc.IntoElem();
		if (!objDoc.FindChildElem(_T("serialport")))
		{
			cout<<_T("Invalid system config file[no serialport element]")<<endl;
			return false;
		}
		m_nPortNo = _ttoi(objDoc.GetChildData().c_str());

		if (!objDoc.FindChildElem(_T("virtualserialport")))
		{
			cout<<_T("Invalid system config file[no virtualserialport element]")<<endl;
			return false;
		}
		m_nVirPortNo = _ttoi(objDoc.GetChildData().c_str());

		if (!objDoc.FindChildElem(_T("baudrate")))
		{
			cout<<_T("Invalid system config file[no baudrate element]")<<endl;
			return false;
		}
		m_nBaud = _ttoi(objDoc.GetChildData().c_str());

		if (!objDoc.FindChildElem(_T("parity")))
		{
			cout<<_T("Invalid system config file[no parity element]")<<endl;
			return false;
		}
		m_strParity = objDoc.GetChildData().c_str();

		if (!objDoc.FindChildElem(_T("databit")))
		{
			cout<<_T("Invalid system config file[no databit element]")<<endl;
			return false;
		}
		m_nDataBit = _ttoi(objDoc.GetChildData().c_str());

		if (!objDoc.FindChildElem(_T("stopbit")))
		{
			cout<<_T("Invalid system config file[no stopbit element]")<<endl;
			return false;
		}
		m_nStopBit = _ttoi(objDoc.GetChildData().c_str());
		objDoc.OutOfElem();

		//command-begin
		if (!objDoc.FindChildElem(_T("command")))
		{
			cout<<_T("Invalid system config file[no localcommand element].")<<endl;
			return false;
		}
		objDoc.IntoElem();
		//----------------------------monitorcommand
		if (!objDoc.FindChildElem(_T("monitorcommand")))
		{
			cout<<_T("Invalid system config file[no monitorcommand element]")<<endl;
			return false;
		}

		objDoc.IntoElem();
		if (!objDoc.FindChildElem(_T("begin")))
		{
			cout<<_T("Invalid system config file[no begin element]")<<endl;
			return false;
		}
		m_pMonitorCommand->nBegin = _ttoi(objDoc.GetChildData().c_str());

		if (!objDoc.FindChildElem(_T("id")))
		{
			cout<<_T("Invalid system config file[no id element]")<<endl;
			return false;
		}
		m_pMonitorCommand->nId = _ttoi(objDoc.GetChildData().c_str());

		if (!objDoc.FindChildElem(_T("tvwallbegin")))
		{
			cout<<_T("Invalid system config file[no tvwallbegin element]")<<endl;
			return false;
		}
		m_pMonitorCommand->nTvWallBegin = _ttoi(objDoc.GetChildData().c_str());

		if (!objDoc.FindChildElem(_T("tvwallend")))
		{
			cout<<_T("Invalid system config file[no tvwallend element]")<<endl;
			return false;
		}
		m_pMonitorCommand->nTvWallEnd = _ttoi(objDoc.GetChildData().c_str());

		if (!objDoc.FindChildElem(_T("control")))
		{
			cout<<_T("Invalid system config file[no control element]")<<endl;
			return false;
		}
		m_pMonitorCommand->nControl = _ttoi(objDoc.GetChildData().c_str());

		if (!objDoc.FindChildElem(_T("regulate")))
		{
			cout<<_T("Invalid system config file[no regulate element]")<<endl;
			return false;
		}
		m_pMonitorCommand->nRegulate = _ttoi(objDoc.GetChildData().c_str());

		if (!objDoc.FindChildElem(_T("end")))
		{
			cout<<_T("Invalid system config file[no end element]")<<endl;
			return false;
		}
		m_pMonitorCommand->nEnd = _ttoi(objDoc.GetChildData().c_str());
		objDoc.OutOfElem();
		//--------------------------------tvwall command
		if (!objDoc.FindChildElem(_T("tvwallcommand")))
		{
			cout<<_T("Invalid system config file[no tvwallcommand element]")<<endl;
			return false;
		}

		objDoc.IntoElem();
		if (!objDoc.FindChildElem(_T("begin")))
		{
			cout<<_T("Invalid system config file[no begin element]")<<endl;
			return false;
		}
		m_pTvWallCommand->nBegin = _ttoi(objDoc.GetChildData().c_str());

		if (!objDoc.FindChildElem(_T("id")))
		{
			cout<<_T("Invalid system config file[no id element]")<<endl;
			return false;
		}
		m_pTvWallCommand->nId = _ttoi(objDoc.GetChildData().c_str());

		if (!objDoc.FindChildElem(_T("tvwallbegin")))
		{
			cout<<_T("Invalid system config file[no tvwallbegin element]")<<endl;
			return false;
		}
		m_pTvWallCommand->nTvWallBegin = _ttoi(objDoc.GetChildData().c_str());

		if (!objDoc.FindChildElem(_T("tvwallend")))
		{
			cout<<_T("Invalid system config file[no tvwallend element]")<<endl;
			return false;
		}
		m_pTvWallCommand->nTvWallEnd = _ttoi(objDoc.GetChildData().c_str());

		if (!objDoc.FindChildElem(_T("control")))
		{
			cout<<_T("Invalid system config file[no control element]")<<endl;
			return false;
		}
		m_pTvWallCommand->nControl = _ttoi(objDoc.GetChildData().c_str());

		if (!objDoc.FindChildElem(_T("regulate")))
		{
			cout<<_T("Invalid system config file[no regulate element]")<<endl;
			return false;
		}
		m_pTvWallCommand->nRegulate = _ttoi(objDoc.GetChildData().c_str());

		if (!objDoc.FindChildElem(_T("end")))
		{
			cout<<_T("Invalid system config file[no end element]")<<endl;
			return false;
		}
		m_pTvWallCommand->nEnd = _ttoi(objDoc.GetChildData().c_str());
		objDoc.OutOfElem();

		//command-end
		objDoc.OutOfElem();

		m_bLoad = true;
		SaveConfig();
	}
	catch(...)
	{
		cout<<_T("Invalid system config file catch exception.")<<endl;
		return false;
	}

	return true;
}
bool CSystemConfig::SaveConfig()
{
	TCHAR szAppPath[MAX_PATH] = {_T("")};
	memset(szAppPath, 0, MAX_PATH);
	int nLength = m_strConfigFilePath.length()>MAX_PATH?MAX_PATH:m_strConfigFilePath.length();
	memcpy(szAppPath , m_strConfigFilePath.c_str(), nLength);

	TCHAR szCfgFile[MAX_PATH] = {_T("")};
	CFileUtil::GetFullFileName(szAppPath,SYSTEM_CONFIG_FILE,szCfgFile,MAX_PATH);

	if(!CFileUtil::IsFileOrDirExist(szCfgFile))
		CFileUtil::CreateFile(szCfgFile);

	try
	{
		CMarkup objDoc;
		objDoc.SetDoc("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");

		objDoc.AddElem("config");

		objDoc.AddChildElem("configcenter");
		objDoc.IntoElem();
		objDoc.AddChildElem("serialport", m_nPortNo);
		objDoc.AddChildElem("virtualserialport", m_nVirPortNo);
		objDoc.AddChildElem("baudrate", m_nBaud);
		objDoc.AddChildElem("parity", m_strParity);
		objDoc.AddChildElem("databit", m_nDataBit);
		objDoc.AddChildElem("stopbit", m_nStopBit);
		objDoc.OutOfElem();

		objDoc.AddChildElem("command");
		{
			objDoc.IntoElem();
			objDoc.AddChildElem("monitorcommand");
			{
				objDoc.IntoElem();
				objDoc.AddChildElem("begin", m_pMonitorCommand->nBegin);
				objDoc.AddChildElem("id", m_pMonitorCommand->nId);
				objDoc.AddChildElem("tvwallbegin", m_pMonitorCommand->nTvWallBegin);
				objDoc.AddChildElem("tvwallend", m_pMonitorCommand->nTvWallEnd);
				objDoc.AddChildElem("control", m_pMonitorCommand->nControl);
				objDoc.AddChildElem("regulate", m_pMonitorCommand->nRegulate);
				objDoc.AddChildElem("end", m_pMonitorCommand->nEnd);
				objDoc.OutOfElem();
			}
			objDoc.AddChildElem("tvwallcommand");
			{
				objDoc.IntoElem();
				objDoc.AddChildElem("begin", m_pTvWallCommand->nBegin);
				objDoc.AddChildElem("id", m_pTvWallCommand->nId);
				objDoc.AddChildElem("tvwallbegin", m_pTvWallCommand->nTvWallBegin);
				objDoc.AddChildElem("tvwallend", m_pTvWallCommand->nTvWallEnd);
				objDoc.AddChildElem("control", m_pTvWallCommand->nControl);
				objDoc.AddChildElem("regulate", m_pTvWallCommand->nRegulate);
				objDoc.AddChildElem("end", m_pTvWallCommand->nEnd);
				objDoc.OutOfElem();
			}
			objDoc.OutOfElem();
		}

		return objDoc.Save(szCfgFile);
	}
	catch(...)
	{
		return false;
	}
}

UINT CSystemConfig::GetPortNo()
{
	return m_nPortNo;
}
void CSystemConfig::SetPortNo(UINT portNo)
{
	m_nPortNo = portNo;
}

UINT CSystemConfig::GetVirPortNo()
{
	return m_nVirPortNo;
}
void CSystemConfig::SetVirPortNo(UINT virPortNo)
{
	m_nVirPortNo = virPortNo;
}

UINT CSystemConfig::GetBaud()
{
	return m_nBaud;
}

void CSystemConfig::SetBuad(UINT baud)
{
	m_nBaud = baud;
}

string CSystemConfig::GetParity()
{
	return m_strParity;
}

void CSystemConfig::SetParity(string parity)
{
	m_strParity = parity;
}

UINT CSystemConfig::GetDataBit()
{
	return m_nDataBit;
}
void CSystemConfig::SetDataBit(UINT databit)
{
	m_nDataBit = databit;
}

UINT CSystemConfig::GetStopBit()
{
	return m_nStopBit;
}
void CSystemConfig::SetStopBit(UINT stopbit)
{
	m_nStopBit = stopbit;
}

PCOMMAND CSystemConfig::GetTvWallCommand()
{
	return m_pTvWallCommand;
}
void CSystemConfig::SetTvWallCommand(PCOMMAND pTvWallCommand)
{
	m_pTvWallCommand = pTvWallCommand;
}

PCOMMAND CSystemConfig::GetMonitorCommand()
{
	return m_pMonitorCommand;
}
void CSystemConfig::SetMonitorCommand(PCOMMAND pMonitorCommand)
{
	m_pMonitorCommand = pMonitorCommand;
}
